package com.lujieni.async.controller;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lujieni.async.service.AsyncTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.Future;

/**
 * @Auther lujieni
 * @Date 2020/5/20
 */
@RestController
public class AsyncTaskController {
    @Autowired
    private AsyncTask asyncTask;

    /**
     * task1和task2这2个都是异步的方法因为加了@Async标签,
     * 那我们该如何得到结果呢?通过f1.isDone即可等待异步
     * 方法调用完成,这里是阻塞的!!!
     * @return
     * @throws Exception
     */
    @GetMapping("/do")
    public String doTask() throws Exception{
        long start = System.currentTimeMillis();
        Future<Boolean> f1 = asyncTask.task1(); //异步方法
        Future<Boolean> f2 = asyncTask.task2(); //异步方法
        System.out.println("doTask-main:"+Thread.currentThread().getName()); //http-nio-8080-exec-2
        while (!f1.isDone() || !f2.isDone()){
            if(f1.isDone() && f2.isDone()){
                System.out.println("f1:"+f1.get());
                System.out.println("f2:"+f2.get());
                break;
            }
        }
        //asyncTask.task2();
        long end = System.currentTimeMillis();
        return "task任务总耗时:"+(end-start)+"ms";
       /* f2.get();
        System.out.println("hello");*/
    }

    @GetMapping("/work")
    public String work() throws Exception{
        asyncTask.work();
        return "success";
    }

    @GetMapping("/json")
    public void jason() throws IOException {
        String json = "[{\"age\":12,\"name\":\"王小虎\"},{\"age\":35,\"name\":\"小鹿\"}]"; // \" = "
        ObjectMapper mapper = new ObjectMapper();
        JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, Student.class);
        List<Student> list = mapper.readValue(json, javaType);
        for(Student student :list){
            System.out.println(student);
        }
    }

    @GetMapping(value = "doTask1")
    public void doTask1(){
        try {
            asyncTask.task1();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}

class Student{

    private Integer age;
    private String name;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
